createOrUpdateIssue.js ➔ ???   B
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 118
Code Lines 65

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 65
nc 2
dl 0
loc 118
c 1
b 0
f 0
rs 8.1454
nop 5

7 Functions

Rating   Name   Duplication   Size   Complexity  
A createOrUpdateIssue.js ➔ ... ➔ createIssue 0 11 1
A createOrUpdateIssue.js ➔ ... ➔ parseCustomFields 0 14 2
A createOrUpdateIssue.js ➔ ... ➔ processFields 0 22 2
A createOrUpdateIssue.js ➔ ... ➔ requestIssue 0 30 1
A createOrUpdateIssue.js ➔ ... ➔ updateIssue 0 8 1
A createOrUpdateIssue.js ➔ ... ➔ replaceNowString 0 15 1
A createOrUpdateIssue.js ➔ ... ➔ ??? 0 3 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
'use strict'
2
3
const _ = require('lodash')
0 ignored issues
show
Unused Code introduced by
The constant _ seems to be never used. Consider removing it.
Loading history...
4
const debug = require('debug')('jira-resource')
5
const moment = require('moment')
0 ignored issues
show
Unused Code introduced by
The constant moment seems to be never used. Consider removing it.
Loading history...
6
const request = require('request')
0 ignored issues
show
Unused Code introduced by
The constant request seems to be never used. Consider removing it.
Loading history...
7
8
const debugResponse = require('./debugResponse.js')
0 ignored issues
show
Unused Code introduced by
The constant debugResponse seems to be never used. Consider removing it.
Loading history...
9
const replaceTextFileString = require('./replaceTextFileString.js')
0 ignored issues
show
Unused Code introduced by
The constant replaceTextFileString seems to be never used. Consider removing it.
Loading history...
10
11
module.exports = (baseFileDir, existingIssue, source, params, callback) => {
12
13
    if ( existingIssue ) {
14
        return updateIssue((error) => {
15
            callback(error, existingIssue)
16
        })
17
    }
18
19
    return createIssue((error, newIssue) => {
20
        callback(error, newIssue)
21
    })
22
23
    function createIssue (done) {
0 ignored issues
show
Bug introduced by
The function createIssue is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var createIssue = function() { /* ... */ }; instead.
Loading history...
24
        debug('Issue doesn\'t exist, creating new issue...')
25
26
        return requestIssue(source.url + '/rest/api/2/issue/', 'POST', (error, response, body) => {
27
            if ( !error && !body ) {
28
                return done(new Error('Could not create issue.'))
29
            }
30
31
            done(error, body)
32
        })
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
33
    }
34
35
    function updateIssue (done) {
0 ignored issues
show
Bug introduced by
The function updateIssue is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var updateIssue = function() { /* ... */ }; instead.
Loading history...
36
        let issueId = existingIssue.id
37
        let issueKey = existingIssue.key
38
39
        debug('Issue exists [%s], updating issue...', issueKey)
40
41
        return requestIssue(source.url + '/rest/api/2/issue/' + issueId, 'PUT', done)
42
    }
43
44
    function requestIssue (issueUrl, method, callback) {
0 ignored issues
show
Bug introduced by
The function requestIssue is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var requestIssue = function() { /* ... */ }; instead.
Loading history...
45
46
        let issue = {
47
            fields: processFields()
48
        }
49
50
        debug('Sending issue: %s', JSON.stringify(issue, null, 2))
51
52
        request({
53
            method: method,
54
            uri:    issueUrl,
55
            auth:   {
56
                username: source.username,
57
                password: source.password
58
            },
59
            json:   issue
60
        }, (error, response, body) => {
61
            if ( error ) {
62
                return callback(error)
63
            }
64
65
            debugResponse(response)
66
67
            if ( response.statusCode < 200 || 300 <= response.statusCode ) {
68
                return callback(new Error('Could not update Jira.'))
69
            }
70
71
            callback(error, response, body)
72
        })
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
73
    }
74
75
    function processFields () {
0 ignored issues
show
Bug introduced by
The function processFields is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var processFields = function() { /* ... */ }; instead.
Loading history...
76
        let fields = params.fields || {}
77
78
        fields.summary = params.summary
79
80
        fields = _.merge(parseCustomFields(params), fields)
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
81
82
        fields = _(fields)
83
            .mapValues((value) => {
84
                return replaceTextFileString(baseFileDir, value)
85
            })
86
            .mapValues(replaceNowString)
87
            .value()
88
89
        fields.project = { key: source.project }
90
91
        if ( params.issue_type ) {
92
            fields.issuetype = { name: params.issue_type }
93
        }
94
95
        return fields
96
    }
97
98
    function replaceNowString (value) {
0 ignored issues
show
Bug introduced by
The function replaceNowString is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var replaceNowString = function() { /* ... */ }; instead.
Loading history...
99
        value = String(value)
100
101
        return value.replace(/\$NOW([-+][0-9]+)?([ywdhms])?/, (match, change, unit) => {
102
            let date = moment()
103
104
            unit = unit || 'm'
105
106
            if ( change ) {
107
                date = date.add(change, unit)
108
            }
109
110
            return date.format()
111
        })
112
    }
113
114
    function parseCustomFields (params) {
0 ignored issues
show
Bug introduced by
The function parseCustomFields is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var parseCustomFields = function() { /* ... */ }; instead.
Loading history...
115
        if ( !params.custom_fields ) {
116
            return {}
117
        }
118
119
        return _(params.custom_fields)
120
            .mapKeys((value) => {
121
                return 'customfield_' + value.id
122
            })
123
            .mapValues((value) => {
124
                return value.value
125
            })
126
            .value()
127
    }
128
}
129